package cn.itcast.bos.service.take_delivery.Impl;


import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder.Operator;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.itcast.bos.dao.take_delivery.WayBillRepository;
import cn.itcast.bos.domain.take_delivery.WayBill;
import cn.itcast.bos.index.WayBillIndexRepository;
import cn.itcast.bos.service.take_delivery.WayBillService;

@Service
@Transactional
public class WayBillServiceImpl implements WayBillService {
	
	@Autowired
	private WayBillRepository wayBillRepository;
	
	@Autowired
	private WayBillIndexRepository wayBillIndexRepository;
	
	@Override
	public void save(WayBill waybill) {
		//将实体类waybill变为持久对象
		WayBill persitentWaybill = wayBillRepository.findByWayBillNum(waybill.getWayBillNum());
		//判断数据库中waybill表中数据是否存在
		if(persitentWaybill!=null && persitentWaybill.getId()!=null){
		//运单已经创建,判断运单状态是否为待发货状态
			if(persitentWaybill.getSignStatus()==1){
				//待发货状态,将运单信息复制给持久态的运单
				Integer id = persitentWaybill.getId();
				//使用beanutils的工具类将从客户端传来的实体类复制给持久库
				try {
					BeanUtils.copyProperties(persitentWaybill, waybill);
				} catch (Exception  e) {
					e.printStackTrace();
				}
				//保存id(利用持久类对象的自动更新数据库的能力)
				persitentWaybill.setId(id);
				persitentWaybill.setSignStatus(1);
				//更新索引
				wayBillIndexRepository.save(persitentWaybill);
			}else{
				throw new RuntimeException("该运单已经保存并发出,无法进行修改!!!");
			}
		}else{
			//运单没有被创建过
			//设置运单状态(1:待发货)
			waybill.setSignStatus(1);
			//不存在,调用dao层方法,保存数据
			wayBillRepository.save(waybill);
			//建立索引
			wayBillIndexRepository.save(waybill);
		}
	
	}

	@Override
	public Page<WayBill> pageQuery(WayBill wayBill,Pageable pageable) {
		//情况一: 当所有的查询条件为空时,直接到数据库查询
		if(StringUtils.isBlank(wayBill.getWayBillNum())
			 && StringUtils.isBlank(wayBill.getSendAddress())
			 && StringUtils.isBlank(wayBill.getRecAddress())
			 && StringUtils.isBlank(wayBill.getSendProNum())
			 && (wayBill.getSignStatus()==null || wayBill.getSignStatus()==0)){
			return wayBillRepository.findAll(pageable);
		}
		//情况二: 当查询条件不为空时,连接索引库查询
		//创建布尔查询对象,多条件组合查询
		BoolQueryBuilder boolQuery = new BoolQueryBuilder();
		//运单号查询--等值查询
		if(StringUtils.isNotBlank(wayBill.getWayBillNum())){
			QueryBuilder termQuery = new TermQueryBuilder("wayBillNum",wayBill.getWayBillNum());
			boolQuery.must(termQuery);
		}
		//收货地查询---模糊查询
		if(StringUtils.isNotBlank(wayBill.getSendAddress())){
			QueryBuilder wildcardQuery = new WildcardQueryBuilder("recAddress", "*"+wayBill.getRecAddress()+"*");
			boolQuery.must(wildcardQuery);
		}
		//快递产品类型查询--等值查询
		if(StringUtils.isNotBlank(wayBill.getSendProNum())){
			System.out.println("快递产品类型为:"+wayBill.getSendProNum());
//			QueryBuilder wildcardQuery = new WildcardQueryBuilder("sendProNum", "*"+wayBill.getSendProNum()+"*");
//			boolQuery.must(wildcardQuery);
			
			//情况一:输入信息是词条的一部分,如"武"---"武汉市洪山区长城科技园" 
			QueryBuilder wildcardQuery = new WildcardQueryBuilder("sendProNum", "*"+wayBill.getSendProNum()+"*");
			//情况二:输入的查询信息是多个词条的组合,进行分词后,然后再进行匹配, 如"武汉长城"---"武汉市洪山区长城科技园"
			QueryBuilder QueryStringQuery = new QueryStringQueryBuilder(wayBill.getSendProNum())
					.field("sendProNum").defaultOperator(Operator.AND);
			BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
			boolQueryBuilder.should(QueryStringQuery);
			boolQueryBuilder.should(wildcardQuery);
			boolQuery.must(boolQueryBuilder);
			
			
		}
		//运单状态查询---等值查询
		if(wayBill.getSignStatus()!=null && wayBill.getSignStatus()!=0){
			QueryBuilder termQuery = new TermQueryBuilder("signStatus",wayBill.getSignStatus());
			boolQuery.must(termQuery);
		}
		//多个词条组合查询(发货地址查询)
		
		if(StringUtils.isNotBlank(wayBill.getSendAddress())){
			//情况一:输入信息是词条的一部分,如"武"---"武汉市洪山区长城科技园" 
			QueryBuilder wildcardQuery = new WildcardQueryBuilder("sendAddress", "*"+wayBill.getSendAddress()+"*");
			//情况二:输入的查询信息是多个词条的组合,进行分词后,然后再进行匹配, 如"武汉长城"---"武汉市洪山区长城科技园"
			QueryBuilder QueryStringQuery = new QueryStringQueryBuilder(wayBill.getSendAddress())
					.field("sendAddress").defaultOperator(Operator.AND);
			BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
			boolQueryBuilder.should(QueryStringQuery);
			boolQueryBuilder.should(wildcardQuery);
			boolQuery.must(boolQueryBuilder);
		}
	
		//创建serchQuery对象
		SearchQuery searchQuery = new NativeSearchQuery(boolQuery);
		searchQuery.setPageable(pageable);
		return wayBillIndexRepository.search(searchQuery);
		
	}

	@Override
	public WayBill findWayBillDataByWayBillNum(String wayBillNum) {
		return wayBillRepository.findByWayBillNum(wayBillNum);
	}

	
	//定时更新索引库数据
	@Override
	public void updataWaybillIndex() {
		List<WayBill> wayBills = wayBillRepository.findAll();
		wayBillIndexRepository.save(wayBills);
	}

	//删除索引库数据
	@Override
	public void deleteWaybillIndex() {
		List<WayBill> wayBills = wayBillRepository.findAll();
		wayBillIndexRepository.delete(wayBills);
	}

	//导出运单信息
	@Override
	public List<WayBill> findWayBills(WayBill wayBill) {
		//情况一: 当所有的查询条件为空时,直接到数据库查询
				if(StringUtils.isBlank(wayBill.getWayBillNum())
					 && StringUtils.isBlank(wayBill.getSendAddress())
					 && StringUtils.isBlank(wayBill.getRecAddress())
					 && StringUtils.isBlank(wayBill.getSendProNum())
					 && (wayBill.getSignStatus()==null || wayBill.getSignStatus()==0)){
					return wayBillRepository.findAll();
				}
				//情况二: 当查询条件不为空时,连接索引库查询
				//创建布尔查询对象,多条件组合查询
				BoolQueryBuilder boolQuery = new BoolQueryBuilder();
				//运单号查询--等值查询
				if(StringUtils.isNotBlank(wayBill.getWayBillNum())){
					QueryBuilder termQuery = new TermQueryBuilder("wayBillNum",wayBill.getWayBillNum());
					boolQuery.must(termQuery);
				}
				//收货地查询---模糊查询
				if(StringUtils.isNotBlank(wayBill.getSendAddress())){
					QueryBuilder wildcardQuery = new WildcardQueryBuilder("recAddress", "*"+wayBill.getRecAddress()+"*");
					boolQuery.must(wildcardQuery);
				}
				//快递产品类型查询--等值查询
				if(StringUtils.isNotBlank(wayBill.getSendProNum())){
					System.out.println("快递产品类型为:"+wayBill.getSendProNum());
					//QueryBuilder wildcardQuery = new WildcardQueryBuilder("sendProNum", "*"+wayBill.getSendProNum()+"*");
					//boolQuery.must(wildcardQuery);
					
					//情况一:输入信息是词条的一部分,如"武"---"武汉市洪山区长城科技园" 
					QueryBuilder wildcardQuery = new WildcardQueryBuilder("sendProNum", "*"+wayBill.getSendProNum()+"*");
					//情况二:输入的查询信息是多个词条的组合,进行分词后,然后再进行匹配, 如"武汉长城"---"武汉市洪山区长城科技园"
					QueryBuilder QueryStringQuery = new QueryStringQueryBuilder(wayBill.getSendProNum())
							.field("sendProNum").defaultOperator(Operator.AND);
					BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
					boolQueryBuilder.should(QueryStringQuery);
					boolQueryBuilder.should(wildcardQuery);
					boolQuery.must(boolQueryBuilder);
					
					
				}
				//运单状态查询---等值查询
				if(wayBill.getSignStatus()!=null && wayBill.getSignStatus()!=0){
					QueryBuilder termQuery = new TermQueryBuilder("signStatus",wayBill.getSignStatus());
					boolQuery.must(termQuery);
				}
				//多个词条组合查询(发货地址查询)
				
				if(StringUtils.isNotBlank(wayBill.getSendAddress())){
					//情况一:输入信息是词条的一部分,如"武"---"武汉市洪山区长城科技园" 
					QueryBuilder wildcardQuery = new WildcardQueryBuilder("sendAddress", "*"+wayBill.getSendAddress()+"*");
					//情况二:输入的查询信息是多个词条的组合,进行分词后,然后再进行匹配, 如"武汉长城"---"武汉市洪山区长城科技园"
					QueryBuilder QueryStringQuery = new QueryStringQueryBuilder(wayBill.getSendAddress())
							.field("sendAddress").defaultOperator(Operator.AND);
					BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
					boolQueryBuilder.should(QueryStringQuery);
					boolQueryBuilder.should(wildcardQuery);
					boolQuery.must(boolQueryBuilder);
				}
			
				//创建serchQuery对象
				SearchQuery searchQuery = new NativeSearchQuery(boolQuery);
				Pageable pageable = new PageRequest(0,10000);
				searchQuery.setPageable(pageable);
				//Page<WayBill> page = wayBillIndexRepository.search(searchQuery);
				return wayBillIndexRepository.search(searchQuery).getContent();
	}


}
